package com.share.tool.mock.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.share.common.common.Page;
import com.share.common.utils.GroovyUtil;
import com.share.tool.mock.mapper.VariableMapper;
import com.share.tool.mock.model.db.Variable;
import com.share.tool.mock.model.vo.VariablePageListReq;
import com.share.tool.mock.service.VariableService;
import groovy.lang.GroovyObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class VariableServiceImpl extends ServiceImpl<VariableMapper, Variable> implements VariableService {
    @Resource
    private VariableMapper mockVariableMapper;

    private Map<String, Variable> variableConfigMap = new HashMap<>();
    private Map<String, GroovyObject> groovyObjectMap = new HashMap<>();

    /*初始化方法*/
    @Override
    public Object init() {
        Map<String, Variable> morkVariableMap = new HashMap<>();
        LambdaQueryWrapper<Variable> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Variable::getIsValid, 1);
        List<Variable> mockVariables = mockVariableMapper.selectList(queryWrapper);
        for (Variable item : mockVariables) {
            morkVariableMap.put(item.getCode(), item);
        }

        if (morkVariableMap != null) {
            variableConfigMap = morkVariableMap;
        }

        Map<String, GroovyObject> tmpGroovyObjectMap = new HashMap<>();
        Collection<Variable> values = morkVariableMap.values();
        for (Variable item : values) {
            try {
                tmpGroovyObjectMap.put(item.getCode(), GroovyUtil.createGroovyObject(item.getGroovy()));
            } catch (Exception e) {
                log.error("groovy初始化失败po={}", JSON.toJSONString(item), e);
                throw new RuntimeException("配置异常groovy=" + item.getGroovy());
            }
        }
        if (!CollectionUtils.isEmpty(tmpGroovyObjectMap)) {
            groovyObjectMap = tmpGroovyObjectMap;
        }
        return values;
    }

    @Override
    public Variable getByVariableCode(String code) {
        return variableConfigMap.get(code);
    }

    @Override
    public Object exeGroovyScript(String code, String method, Object param) {
        GroovyObject groovyObject = groovyObjectMap.get(code);
        try {
            return groovyObject.invokeMethod(method, param);
        } catch (Exception e) {
            log.error("groovy脚本执行异常code={},param={},groovy={}", code, param, groovyObject, e);
            return null;
        }
    }

    @Override
    public Page pageList(VariablePageListReq req) {
        PageHelper.startPage(req.getPageNum(), req.getPageSize());
        LambdaQueryWrapper<Variable> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(req.getCode())) {
            queryWrapper.like(Variable::getCode, req.getCode());
        }
        if (StringUtils.isNotBlank(req.getName())) {
            queryWrapper.like(Variable::getName, req.getName());
        }
        if (StringUtils.isNotBlank(req.getDefaultValue())) {
            queryWrapper.like(Variable::getDefaultValue, req.getDefaultValue());
        }
        if (StringUtils.isNotBlank(req.getDataType())) {
            queryWrapper.like(Variable::getDataType, req.getDataType());
        }
        if (StringUtils.isNotBlank(req.getGroovy())) {
            queryWrapper.like(Variable::getGroovy, req.getGroovy());
        }
        List<Variable> list = mockVariableMapper.selectList(queryWrapper);
        return new Page<>(list, new PageInfo<>(list).getTotal(), req);
    }
}
